Output=function(){
  var self=this;

  self.canvas = $('#canvas')[0];
  self.ctx = canvas.getContext('2d');

  self.W=665;
  self.H=450;
  self.leftOffset=45;
  self.rightOffset=20;
  self.topOffset=50;
  self.gridCount=20;
  self.markW=5;
  self.texdDistance=2;

  self.taskH=40;
  self.taskOffset=30;
  self.gridIncrement=2;

  self.initAlt=20;
  self.initH=10;
  self.initW=10;


  //it initializes (clears) the board
  self.clear=function(){
    Log("output.clear");
    utils.resetColors();
    self.ctx.fillStyle = "#ddd";
    self.ctx.fillRect(0, 0, self.W, self.H);

    //drawing orange Horizontal line
    self.ctx.beginPath();
    self.ctx.moveTo(self.leftOffset,self.topOffset);
    self.ctx.lineTo(self.W-self.rightOffset,self.topOffset);
    self.ctx.strokeStyle="orange";
    self.ctx.stroke();

    //drawing marks
    self.ctx.strokeStyle="black";
    self.ctx.textAlign="center";
    self.ctx.font="12pt courier";
    for(var i=0;i<self.gridCount;i++){
      self.ctx.beginPath();
      self.ctx.moveTo(self.leftOffset+i*(self.W/self.gridCount),self.topOffset-self.markW);
      self.ctx.lineTo(self.leftOffset+i*(self.W/self.gridCount),self.topOffset+self.markW);
      self.ctx.strokeText(
        i*self.gridIncrement,
        self.leftOffset+i*(self.W/self.gridCount),
        self.topOffset-self.markW-self.texdDistance
      );
      self.ctx.stroke();
    }
    return self;
  }
  self.drawTrack=function(taskState){
    var numTask=taskState.id;
    Log("output.drawTrack");
    self.ctx.strokeStyle="black";
    self.ctx.textAlign="left";
    self.ctx.font="12pt courier";

    self.ctx.beginPath();
    self.ctx.moveTo(self.leftOffset, self.topOffset+(numTask+1)*self.taskH);
    self.ctx.lineTo(self.W-self.rightOffset, self.topOffset+(numTask+1)*self.taskH);
    self.ctx.strokeText(
      'T'+numTask,
      self.leftOffset-self.taskOffset,
      self.topOffset+(numTask+1)*self.taskH
    );
    self.ctx.stroke();
    return self;
  }
  self.drawInit=function(taskState){
    var numTask=taskState.id;
    Log("output.drawInit("+taskState.id+"): "+taskState.init);
    self.ctx.strokeStyle = "gray";
    self.ctx.fillStyle = "gray";
    self.ctx.beginPath();
    self.ctx.moveTo(
      self.leftOffset+taskState.init*self.W/self.gridCount/self.gridIncrement-self.initW,
      self.topOffset+(numTask+1)*self.taskH-self.initAlt-self.initH
    );
    self.ctx.lineTo(
      self.leftOffset+taskState.init*self.W/self.gridCount/self.gridIncrement+self.initW,
      self.topOffset+(numTask+1)*self.taskH-self.initAlt-self.initH
    );
    self.ctx.lineTo(
      self.leftOffset+taskState.init*self.W/self.gridCount/self.gridIncrement,
      self.topOffset+(numTask+1)*self.taskH-self.initAlt
    );
    self.ctx.closePath();
    self.ctx.fill();
    return self;
  }
  self.drawTaskState=function(taskState){
    var numTask=taskState.id;
    Log("output.drawTaskState("+taskState.id+"): "+taskState.state);
    if(taskState.state=='not inited' || taskState.state=='finished')return self;
    else if(taskState.state=='suspended') self.ctx.fillStyle = 'cyan';
    else if(taskState.state=='blocked') self.ctx.fillStyle = 'black';
    else self.ctx.fillStyle = utils.getColor(taskState.action);
    self.ctx.fillRect(
      self.leftOffset+(taskState.totalTime-1)*self.W/self.gridCount/self.gridIncrement,
      self.topOffset+(numTask+1)*self.taskH-self.initAlt,
      self.W/self.gridCount/self.gridIncrement,
      self.initAlt-1
    );
    return self;
  }
  self.printSummary=function(taskQueue){
    Log('summary:');
    var respTimes='';
    var RIPTimes='';
    var execSum=0;
    var execTotal=0;
    for(var i=0;i<taskQueue.length;i++){
      Log(taskQueue[i].summary);
      respTimes+=html.li('T'+i+': '+taskQueue[i].summary[1]);
      RIPTimes+=html.li('T'+i+': '+taskQueue[i].summary[3]);
      execSum+=taskQueue[i].summary[2];
      execTotal+=taskQueue[i].summary[1];
    }
    var summary=$('#summary ul');
    summary.html(html.li('Total tasks: '+taskQueue.length));
    summary.append(html.li('Utilization factor: '+(Math.round(execSum/execTotal*100))+'%'));
    summary.append(html.li('Response times:'+html.ul(respTimes)));
    summary.append(html.li('RIP times:'+html.ul(RIPTimes)));
  }
}

output=new Output();


